package com.berwin.syncer.network;

import com.berwin.syncer.listener.FileTransferListener;

import java.io.*;
import java.math.RoundingMode;
import java.net.Socket;
import java.text.DecimalFormat;

public class SessionFile {


    private boolean isRunning;
    private Socket socket;
    // 下载保存的路径
    private String downloadDirectory;
    // 上传文件
    private String uploadFile;

    private FileTransferListener listener;

    public SessionFile(Socket socket) {
        this.socket = socket;
    }

    /**
     * 上传文件
     *
     * @param uploadFile
     */
    public void upload(String uploadFile) {
        new Thread(() -> {
            this.uploadFile = uploadFile;
            FileInputStream fis = null;
            DataOutputStream dos = null;
            try {
                File file = new File(this.uploadFile);
                if (file.exists()) {
                    fis = new FileInputStream(file);
                    dos = new DataOutputStream(this.socket.getOutputStream());

                    // 文件名和长度
                    dos.writeUTF(file.getName());
                    dos.flush();
                    dos.writeLong(file.length());
                    dos.flush();

                    // 开始传输文件
//                    System.out.println("======== 开始传输文件 ========");
                    if (listener != null)
                        listener.onStart(this, file.getParent(), file.getName());
                    byte[] bytes = new byte[1024];
                    int length = 0;
                    long progress = 0;
                    while ((length = fis.read(bytes, 0, bytes.length)) != -1) {
                        dos.write(bytes, 0, length);
                        dos.flush();
                        progress += length;

                        int percent = (int) (100 * progress / file.length());
                        if (listener != null)
                            listener.onProgress(this, percent);
//                        System.out.println("| " + percent + "% |");
                    }
                    fis.close();
//                    System.out.println("======== 文件传输成功 ========");
                    if (listener != null)
                        listener.onFinished(this, file.getParent(), file.getName());
                }
            } catch (Exception e) {
                e.printStackTrace();
                if (listener != null)
                    listener.onError(this, e.toString());
            }
//            finally {
//                try {
//                    if (fis != null)
//                        fis.close();
//                    if (dos != null)
//                        dos.close();
//                    SessionFile.this.socket.close();
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
        }).start();
    }

    /**
     * 下载文件
     *
     * @param directory
     */
    public void start(String directory) {
        this.downloadDirectory = directory;
//        System.out.println("文件目录:" + new File(directory).getAbsolutePath());
        new Thread(() -> {
            this.isRunning = true;
            while (this.isRunning) {
                try {
                    DataInputStream dis = new DataInputStream(socket.getInputStream());
                    // 文件名和长度
                    String fileName = dis.readUTF();
                    long fileLength = dis.readLong();
                    File fileDir = new File(this.downloadDirectory);
                    if (!fileDir.exists()) {
                        fileDir.mkdir();
                    }
                    if (listener != null)
                        listener.onStart(this, fileDir.getParent(), fileName);
                    File file = new File(fileDir.getAbsolutePath() + File.separatorChar + fileName);
                    FileOutputStream fos = new FileOutputStream(file);

                    // 开始接收文件
                    byte[] bytes = new byte[1024];
                    int length = 0;
                    long progress = 0;
                    while ((length = dis.read(bytes, 0, bytes.length)) != -1) {
                        fos.write(bytes, 0, length);
                        fos.flush();
                        progress += length;
                        int percent = (int) (100 * progress / fileLength);
//                        System.out.println(fileName + ":" + percent + "%");
                        if (listener != null)
                            listener.onProgress(this, percent);
                        if (progress >= fileLength)
                            break;
                    }
//                    System.out.println("======== 文件接收成功 [File Name：" + fileName + "] [Size：" + getFormatFileSize(fileLength) + "] ========");
                    fos.close();
                    if (listener != null)
                        listener.onFinished(this, fileDir.getParent(), fileName);
                } catch (IOException e) {
                    e.printStackTrace();
                    this.isRunning = false;
                    if (listener != null)
                        listener.onError(this, e.toString());
                }
            }
//            finally {
//                try {
//                    if (fos != null)
//                        fos.close();
//                    if (dis != null)
//                        dis.close();
//                    socket.close();
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//
//            }
        }).start();
    }

    public FileTransferListener getListener() {
        return listener;
    }

    public void setListener(FileTransferListener listener) {
        this.listener = listener;
    }

    private static DecimalFormat df = null;

    static {
        // 设置数字格式，保留一位有效小数
        df = new DecimalFormat("#0.0");
        df.setRoundingMode(RoundingMode.HALF_UP);
        df.setMinimumFractionDigits(1);
        df.setMaximumFractionDigits(1);
    }

    /**
     * 格式化文件大小
     *
     * @param length
     * @return
     */
    private String getFormatFileSize(long length) {
        double size = ((double) length) / (1 << 30);
        if (size >= 1) {
            return df.format(size) + "GB";
        }
        size = ((double) length) / (1 << 20);
        if (size >= 1) {
            return df.format(size) + "MB";
        }
        size = ((double) length) / (1 << 10);
        if (size >= 1) {
            return df.format(size) + "KB";
        }
        return length + "B";

    }
}
